package com.aierkeji.call.cms.service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.util.CollectionUtils;

import com.aierkeji.call.cms.contants.Contants;
import com.aierkeji.call.cms.dao.jpa.AkjCallClueDao;
import com.aierkeji.call.cms.entity.AkjCallClueFile;
import com.aierkeji.call.cms.entity.vo.AkjCallClueVo;
import com.aierkeji.call.cms.util.AppConfig;
import com.aierkeji.call.cms.util.DateTimeUtils;

public class AkjCallBackupsService {
	private Integer year = null;
	private Integer month = null;
	private Integer day = null;
	private final Logger log = LogManager.getLogger(getClass());
	private String startDateStr;
	private String endDateStr;
	private Date startDate;
	AkjCallClueDao akjCallClueDao;
	int recursiveCount = 0;// 当次递归次数
	int maxRecursive = 21;// 最多递归次数

	private Map<String, Object> map = new HashMap<>();

	private Long createdBy = null;
	private List<AkjCallClueFile> akjCallFiles = new ArrayList<>();

	AkjCallFuntionService akjCallFuntionService = null;

	public AkjCallBackupsService(AkjCallClueDao akjCallClueDao, Long createdBy) {
		this(akjCallClueDao,createdBy,new Date());
	}
	public AkjCallBackupsService(AkjCallClueDao akjCallClueDao, Long createdBy,Date date) {
		super();
		date = date==null?new Date():date;
		LocalDateTime localDateTime = LocalDateTime.now();
		year = localDateTime.getYear();
		month = localDateTime.getMonthValue();
		day = localDateTime.getDayOfMonth();
		startDate = DateTimeUtils.addDay(date, Integer.parseInt(AppConfig.getProperty("backupsDay", "-5")));// 备份N天前的数据
//		startDate = DateTimeUtils.addDay(new Date(), -4);// 备份N天前的数据
		startDateStr = DateTimeUtils.converDateToString(startDate, DateTimeUtils.DATE_PATTERN_DAY);
		endDateStr = startDateStr;
		map.put("endDate", endDateStr);
		map.put("startDate", startDateStr);
		this.createdBy = createdBy;
		map.put("createdBy", createdBy);
		map.put("groupDeleteFlag", false);
		log.info("query map :{}",map);
		this.akjCallClueDao = akjCallClueDao;
		akjCallFuntionService = AkjCallFuntionService.build();
	}
	
	

	public void start() {
		this.doBackUps(1);
		if (!CollectionUtils.isEmpty(akjCallFiles)) {
			int count = akjCallFuntionService.saveClueFileFunction.apply(akjCallFiles);
			
			Date startDate = DateTimeUtils.converStrToTimestamp(startDateStr + " 00:00:00");
			Date endDate = DateTimeUtils.converStrToTimestamp(endDateStr + " 23:59:59");
			akjCallFiles.forEach(k -> {
				int deleteCount = akjCallClueDao.deleteClueByBackups(startDate, endDate, createdBy, 0,k.getCount());
				log.info("delect clue count :{},should count :{}", deleteCount, k.getCount());
			});
			log.info("save akjcallfiles size:{}", count);
			
			int clueHistroyCount = this.akjCallFuntionService.deleteClueHistory(createdBy);
			log.info("delete clueHistroyCount size:{}", clueHistroyCount);

		}else {
			log.info(" ------------no call files-----");
		}

		
	}

	// 备份线索数据到文件
	private void doBackUps(int pageNo) {
		recursiveCount++;
		log.info("start pageno,:{},recursiveCount:{}", pageNo, recursiveCount);
		Page<AkjCallClueVo> page = this.akjCallClueDao.query(pageNo, map,
				Integer.parseInt(AppConfig.getProperty("eachMaxCount", Contants.defaultReportCount)));
		int totalPage = page.getTotalPages();
		List<AkjCallClueVo> list = page.getContent();
		log.info("doBackUps list size:{},totalPage:{}",list.size(),page.getTotalPages());
		if (!CollectionUtils.isEmpty(list)) {
			String str = akjCallFuntionService.writeClueCsvString.apply(list);
			String fileName = "clueList_" + createdBy + "_" + pageNo + "_" + new Date().getTime() + ".csv";
			String path = "backups"+File.separator + year + File.separator + month + File.separator + day + File.separator;
			File baseDir = new File(AppConfig.getProperty("backUpsDir") + path);
			if (!baseDir.exists()) {
				baseDir.mkdirs();
			}
//			if()
			String fileUrl = AppConfig.getProperty("backUpsDir") + path + fileName;
			log.info("backups fileUrl:{}", fileUrl);
			Path basePath = Paths.get(fileUrl);

			try {
				Files.write(basePath, str.getBytes(AppConfig.getProperty("backupsEncord", "GBK")));
				this.saveFile(fileName, path, pageNo, list.size());
			} catch (IOException e) {
				log.error("write file error pageNo:{},map:{}", pageNo, map);
				log.error("", e);
			}
		}
		if (pageNo < totalPage) {
			log.info("page no :{},totalPage:{},recursiveCount:{}", pageNo, totalPage, recursiveCount);
			if (recursiveCount >= maxRecursive) {// 超过最大递归次数
				log.info("超过最大递归次数 recursiveCount:{},maxRecursive:{}", recursiveCount, maxRecursive);
				return;
			}
			pageNo++;
			doBackUps(pageNo);
		}
	}

	// 生成callfile data
	private void saveFile(String fileName, String path, int pageNo, int count) {
		AkjCallClueFile akjCallFile = new AkjCallClueFile();
		akjCallFile.setFileName(fileName);
		akjCallFile.setPath(path);
		akjCallFile.setMark("backups");
		akjCallFile.setCreatedAt(new Date());
		akjCallFile.setSequence(pageNo);
		akjCallFile.setBackupsDate(startDate);
		akjCallFile.setCount(count);
		akjCallFile.setUserId(createdBy);
		akjCallFiles.add(akjCallFile);
	}
}
